package org.base23.video.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.base23.commons.domain.dto.PageResult;
import org.base23.commons.domain.dto.PageQueryParam;
import org.base23.video.domain.dto.CreateAnalysisResultParam;
import org.base23.video.domain.dto.UpdateAnalysisResultParam;
import org.base23.video.domain.dto.UserAnalysisResultDTO;
import org.base23.video.domain.entity.UserAnalysisResult;
import org.base23.video.repository.UserAnalysisResultRepository;
import org.base23.video.service.UserAnalysisResultService;
import org.base23.web.exception.Exceptions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户分析结果服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserAnalysisResultServiceImpl implements UserAnalysisResultService {

    private final UserAnalysisResultRepository repository;

    @Override
    @Transactional
    public Long createAnalysisResult(CreateAnalysisResultParam param) {
        log.info("创建分析结果，用户ID: {}, 结果ID: {}", param.getUserId(), param.getResultId());

        // 检查是否已存在相同的结果
        UserAnalysisResult existing = repository.findByUserIdAndResultId(param.getUserId(), param.getResultId());
        if (existing != null) {
            Exceptions.throwException("该分析结果已存在");
        }

        UserAnalysisResult entity = new UserAnalysisResult();
        BeanUtils.copyProperties(param, entity);
        entity.setCreateTime(System.currentTimeMillis());
        entity.setUpdateTime(System.currentTimeMillis());

        repository.save(entity);
        log.info("分析结果创建成功，ID: {}", entity.getId());
        return entity.getId();
    }

    @Override
    public UserAnalysisResultDTO getAnalysisResultById(Long id) {
        UserAnalysisResult entity = repository.getById(id);
        if (entity == null) {
            Exceptions.throwException("分析结果不存在");
        }
        return convertToDTO(entity);
    }

    @Override
    public UserAnalysisResultDTO getAnalysisResultByUserIdAndResultId(Long userId, String resultId) {
        UserAnalysisResult entity = repository.findByUserIdAndResultId(userId, resultId);
        if (entity == null) {
            Exceptions.throwException("分析结果不存在");
        }
        return convertToDTO(entity);
    }

    @Override
    public PageResult<UserAnalysisResultDTO> pageQueryByUserId(Long userId, PageQueryParam pageParam) {
        Page<UserAnalysisResult> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
        
        LambdaQueryWrapper<UserAnalysisResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserAnalysisResult::getUserId, userId)
                   .orderByDesc(UserAnalysisResult::getCreateTime);

        IPage<UserAnalysisResult> result = repository.page(page, queryWrapper);
        
        List<UserAnalysisResultDTO> dtoList = result.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        return new PageResult<>((int)result.getTotal(), dtoList);
    }

    @Override
    public List<UserAnalysisResultDTO> getAnalysisResultsByUserId(Long userId) {
        List<UserAnalysisResult> entities = repository.findByUserId(userId);
        return entities.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<UserAnalysisResultDTO> getAnalysisResultsByUserIdAndSportType(Long userId, String sportType) {
        List<UserAnalysisResult> entities = repository.findByUserIdAndSportType(userId, sportType);
        return entities.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void updateAnalysisResult(UpdateAnalysisResultParam param) {
        log.info("更新分析结果，ID: {}", param.getId());

        UserAnalysisResult entity = repository.getById(param.getId());
        if (entity == null) {
            Exceptions.throwException("分析结果不存在");
        }

        // 只更新非空字段
        if (param.getSportType() != null) {
            entity.setSportType(param.getSportType());
        }
        if (param.getStatus() != null) {
            entity.setStatus(param.getStatus());
        }
        if (param.getAnalysisData() != null) {
            entity.setAnalysisData(param.getAnalysisData());
        }
        if (param.getSummary() != null) {
            entity.setSummary(param.getSummary());
        }
        if (param.getErrorMessage() != null) {
            entity.setErrorMessage(param.getErrorMessage());
        }
        
        entity.setUpdateTime(System.currentTimeMillis());
        repository.updateById(entity);
        log.info("分析结果更新成功");
    }

    @Override
    @Transactional
    public void deleteAnalysisResult(Long id) {
        log.info("删除分析结果，ID: {}", id);

        UserAnalysisResult entity = repository.getById(id);
        if (entity == null) {
            Exceptions.throwException("分析结果不存在");
        }

        repository.removeById(id);
        log.info("分析结果删除成功");
    }

    @Override
    @Transactional
    public void batchDeleteAnalysisResults(List<Long> ids) {
        log.info("批量删除分析结果，数量: {}", ids.size());
        repository.removeByIds(ids);
        log.info("批量删除成功");
    }

    @Override
    public boolean checkOwnership(Long id, Long userId) {
        UserAnalysisResult entity = repository.getById(id);
        return entity != null && entity.getUserId().equals(userId);
    }

    @Override
    @Transactional
    public void completeAnalysis(Long userId, String resultId, String analysisDataJson, String summary) {
        log.info("完成分析并更新结果，用户ID: {}, 结果ID: {}", userId, resultId);
        
        try {
            UserAnalysisResult entity = repository.findByUserIdAndResultId(userId, resultId);
            if (entity == null) {
                log.warn("未找到用户分析结果记录，用户ID: {}, 结果ID: {}", userId, resultId);
                return;
            }

            // 更新分析结果
            entity.setStatus("COMPLETED");
            entity.setAnalysisData(analysisDataJson);
            entity.setSummary(summary);
            entity.setUpdateTime(System.currentTimeMillis());

            repository.updateById(entity);
            log.info("分析结果更新成功");
            
        } catch (Exception e) {
            log.error("完成分析更新失败，用户ID: {}, 结果ID: {}, 错误: {}", userId, resultId, e.getMessage(), e);
            
            // 尝试标记为失败状态
            try {
                UserAnalysisResult entity = repository.findByUserIdAndResultId(userId, resultId);
                if (entity != null) {
                    entity.setStatus("FAILED");
                    entity.setErrorMessage("分析结果保存失败：" + e.getMessage());
                    entity.setUpdateTime(System.currentTimeMillis());
                    repository.updateById(entity);
                }
            } catch (Exception updateEx) {
                log.error("标记分析失败状态也失败: {}", updateEx.getMessage(), updateEx);
            }
        }
    }

    /**
     * 实体转DTO
     */
    private UserAnalysisResultDTO convertToDTO(UserAnalysisResult entity) {
        UserAnalysisResultDTO dto = new UserAnalysisResultDTO();
        BeanUtils.copyProperties(entity, dto);
        
        // 手动转换时间字段（从Long时间戳转为LocalDateTime）
        if (entity.getCreateTime() != null) {
            dto.setCreateTime(java.time.LocalDateTime.ofInstant(
                java.time.Instant.ofEpochMilli(entity.getCreateTime()), 
                java.time.ZoneId.systemDefault()));
        }
        
        if (entity.getUpdateTime() != null) {
            dto.setUpdateTime(java.time.LocalDateTime.ofInstant(
                java.time.Instant.ofEpochMilli(entity.getUpdateTime()), 
                java.time.ZoneId.systemDefault()));
        }
        
        return dto;
    }
} 